package com.lcq.httplib.client;

import android.util.Log;

import com.lcq.httplib.ErrorEnum;
import com.lcq.httplib.client.adapter.ICallAdapter;
import com.lcq.httplib.client.adapter.RequestParams;
import com.lcq.httplib.client.adapter.StringCallAdapter;
import com.lcq.httplib.callback.Callback;
import com.lcq.httplib.callback.DataCallback;
import com.lcq.httplib.encryptor.Encryptor;
import com.lcq.httplib.parser.DataParser;

import okhttp3.MediaType;
import okhttp3.RequestBody;

public abstract class StringClient<T> extends AbsClient<T> {
    protected final Encryptor encryptor;
    protected final DataParser<T> dataParser;

    public StringClient(ClientParams<T> clientParams) {
        super(clientParams);
        this.encryptor = encryptor();
        this.dataParser = dataParser();
    }

    @Override
    protected ICallAdapter createCallService() {
        RequestParams.Builder<String> builder = new RequestParams.Builder<String>()
                .url(clientParams.getUrl())
                .headers(clientParams.getHeaders())
                .async(clientParams.isAsync())
                .callBack(new Callback<String>() {
                    @Override
                    public void onSuccess(String data) {
                        DataCallback<T> callback = clientParams.getCallback();
                        if (dataParser == null) {
                            callback.onFail(ErrorEnum.DATA_PARSER_NULL.getCode(), ErrorEnum.DATA_PARSER_NULL.getMsg());
                            return;
                        }

                        if (encryptor != null) {
                            try {
                                data = encryptor.decrypt(data);
                            } catch (Exception e) {
                                e.printStackTrace();
                                callback.onFail(ErrorEnum.DECRYPT_FAIL.getCode(), ErrorEnum.DECRYPT_FAIL.getMsg());
                            }
                        }

                        dataParser.parse(data, callback);
                    }

                    @Override
                    public void onFail(int code, String msg) {
                        Log.d("http", "code:" + code + ",msg:" + msg);
                        clientParams.getCallback().onFail(code, msg);
                    }
                });

        if (clientParams.isPost()) {
            builder.requestBody(createRequestBody(clientParams.getPostObject()));
        }

        return new StringCallAdapter(builder.build());
    }

    private RequestBody createRequestBody(Object postParam) {
        String content = null;
        if (postParam == null) {
            Log.d("http", "postParam null");
        } else {
            content = postParamToText(postParam);

            if (encryptor != null) {
                content = encryptor.encrypt(content);
            }
        }

        if (content == null) {
            Log.d("http", "post content is null,set empty String");
            content = "";
        }

        return RequestBody.create(content, MediaType.parse("application/json;charset=utf-8"));
    }

    protected abstract String postParamToText(Object param);

    protected abstract Encryptor encryptor();

    protected abstract DataParser<T> dataParser();
}
